#include <iostream>
#include <thread>
#include <mutex>
static std::mutex mutex;
static std::mutex mutex2;
//当有两把锁，且两个线程都使用到了那么就会出现死锁现象
//解决方法1：两个线程函数加锁顺序一样，但是会出现mutex_thread.cc中的死锁现象
//解决方法2：用std::lock(mutex1, mutex2)加锁，和上面一样会出现上面的情况
//3.自己封装std::lock，利用RAII保证
static int a = 0;
//死锁
// void threadF1()
// {
// 	for (int i = 0; i < 100000; ++i) {
// 		mutex.lock();
// 		mutex2.lock();
// 		{
			
// 			a++;
// 			a--;
// 		}
// 		mutex2.unlock();
// 		mutex.unlock();
// 	}
// }
// void threadF2()
// {
// 	for (int i = 0; i < 100000; ++i) {
		
// 		mutex2.lock();
//         mutex.lock();
// 		{

// 			a++;
// 			a--;
// 		}
//         mutex.unlock();
// 		mutex2.unlock();
		
		
// 	}
// }
//-------------------------------
//解决方法1
// void threadF1()
// {
// 	for (int i = 0; i < 100000; ++i) {
// 		mutex.lock();
// 		mutex2.lock();
// 		{
			
// 			a++;
// 			a--;
// 		}
// 		mutex2.unlock();
// 		mutex.unlock();
// 	}
// }
// void threadF2()
// {
// 	for (int i = 0; i < 100000; ++i) {
// 		mutex.lock();
// 		mutex2.lock();
// 		{

// 			a++;
// 			a--;
// 		}
// 		mutex2.unlock();
// 		mutex.unlock();
		
// 	}
// }
//方法2--------------------------------
// void threadF1()
// {
// 	for (int i = 0; i < 100000; ++i) {
// 		std::lock(mutex, mutex2);
// 		{
			
// 			a++;
// 			a--;
// 		}
// 		mutex2.unlock();
// 		mutex.unlock();
// 	}
// }
// void threadF2()
// {
// 	for (int i = 0; i < 100000; ++i) {
// 		std::lock(mutex, mutex2);
// 		{

// 			a++;
// 			a--;
// 		}
// 		mutex2.unlock();
// 		mutex.unlock();
		
// 	}
// }
//解决方法3---------------------------------------------
class twolock {
public:
    twolock(std::mutex &mutex11, std::mutex &mutex22) : m1(mutex11), m2(mutex22){
        std::lock(m1, m2);
    }
    ~twolock()
    {
        m1.unlock();
        m2.unlock();
    }
private:
    std::mutex &m1;
    std::mutex &m2;

};
void threadF1()
{
	for (int i = 0; i < 100000; ++i) {
		
		{
			twolock lck(mutex, mutex2);
			a++;
			a--;
		}
		
	}
}
void threadF2()
{
	for (int i = 0; i < 100000; ++i) {
		
		{
            twolock lck(mutex, mutex2);
			a++;
			a--;
		}
		
		
	}
}
int main()
{

	std::thread t1(threadF1);
	std::thread t2(threadF2);
	std::cout << a << std::endl;
	t1.join();
	t2.join();

	return 0;
}



